home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / unzip42.zip / MISC.C < prev    next >
C/C++ Source or Header  |  1992-03-19  |  24KB  |  693 lines

  1. /*---------------------------------------------------------------------------
  2.  
  3.   misc.c
  4.  
  5.   This file contains a number of useful but not particularly closely related
  6.   functions; their main claim to fame is that they don't change much, so this
  7.   file should rarely need to be recompiled.  The CRC-32 stuff is from crc32.c;
  8.   do_string() is from nunzip.c; makeword() and makelong() are from unzip.c;
  9.   memset() and memcpy() are from zmemset.c and zmemcpy.c, respectively; and
  10.   dos_to_unix_time() is from set_file_time_and_close() in file_io.c.  ebcdic[],
  11.   check_for_newer(), dateformat(), and return_VMS() are new.  Things lumped
  12.   together here to cut down on the size of unzip.c and the number of associ-
  13.   ated files floating around.
  14.  
  15.   ---------------------------------------------------------------------------
  16.  
  17.   Copyrights:  see accompanying file "COPYING" in UnZip source distribution.
  18.  
  19.   ---------------------------------------------------------------------------*/
  20.  
  21.  
  22. #include "unzip.h"
  23.  
  24.  
  25.  
  26. #ifndef ZIPINFO   /* no need to calculate CRCs */
  27.  
  28. /**************************/
  29. /*  Function UpdateCRC()  */
  30. /**************************/
  31.  
  32.  /*--------------------------------------------------------------------
  33.  
  34.    First, the polynomial itself and its table of feedback terms.  The
  35.    polynomial is
  36.    X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0
  37.  
  38.    Note that we take it "backwards" and put the highest-order term in
  39.    the lowest-order bit.  The X^32 term is "implied"; the LSB is the
  40.    X^31 term, etc.  The X^0 term (usually shown as "+1") results in
  41.    the MSB being 1.
  42.  
  43.    Note that the usual hardware shift register implementation, which
  44.    is what we're using (we're merely optimizing it by doing eight-bit
  45.    chunks at a time) shifts bits into the lowest-order term.  In our
  46.    implementation, that means shifting towards the right.  Why do we
  47.    do it this way?  Because the calculated CRC must be transmitted in
  48.    order from highest-order term to lowest-order term.  UARTs transmit
  49.    characters in order from LSB to MSB.  By storing the CRC this way,
  50.    we hand it to the UART in the order low-byte to high-byte; the UART
  51.    sends each low-bit to hight-bit; and the result is transmission bit
  52.    by bit from highest- to lowest-order term without requiring any bit
  53.    shuffling on our part.  Reception works similarly.
  54.  
  55.    The feedback terms table consists of 256, 32-bit entries.  Notes:
  56.  
  57.        The table can be generated at runtime if desired; code to do so
  58.        is shown later.  It might not be obvious, but the feedback
  59.        terms simply represent the results of eight shift/xor opera-
  60.        tions for all combinations of data and CRC register values.
  61.  
  62.        The values must be right-shifted by eight bits by the "updcrc"
  63.        logic; the shift must be unsigned (bring in zeroes).  On some
  64.        hardware you could probably optimize the shift in assembler by
  65.        using byte-swap instructions.
  66.        polynomial $edb88320
  67.  
  68.    --------------------------------------------------------------------*/
  69.  
  70. ULONG crc_32_tab[] =
  71. {
  72.     0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
  73.     0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
  74.     0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
  75.     0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
  76.     0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
  77.     0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
  78.     0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
  79.     0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
  80.     0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
  81.     0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
  82.     0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
  83.     0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
  84.     0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
  85.     0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
  86.     0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
  87.     0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
  88.     0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
  89.     0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
  90.     0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
  91.     0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
  92.     0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
  93.     0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
  94.     0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
  95.     0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
  96.     0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
  97.     0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
  98.     0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
  99.     0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
  100.     0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
  101.     0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
  102.     0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
  103.     0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
  104.     0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
  105.     0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
  106.     0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
  107.     0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
  108.     0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
  109.     0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
  110.     0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
  111.     0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
  112.     0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
  113.     0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
  114.     0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
  115.     0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
  116.     0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
  117.     0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
  118.     0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
  119.     0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
  120.     0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
  121.     0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
  122.     0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
  123.     0x2d02ef8dL
  124. };
  125.  
  126.  
  127. void UpdateCRC(s, len)
  128. register byte *s;
  129. register int len;
  130.  /* update running CRC calculation with contents of a buffer */
  131. {
  132.     register ULONG crcval = crc32val;
  133.  
  134.  
  135.     while (len--)
  136.         crcval = crc_32_tab[((byte) crcval ^ (*s++)) & 0xff] ^ (crcval >> 8);
  137.     crc32val = crcval;
  138. }
  139.  
  140. #endif /* !ZIPINFO */
  141.  
  142.  
  143.  
  144.  
  145.  
  146. /**************************/
  147. /*  Function do_string()  */
  148. /**************************/
  149.  
  150. int do_string(len, option)      /* return PK-type error code */
  151. unsigned int len;               /* without prototype, UWORD converted to this */
  152. int option;
  153. {
  154.     int block_length, error = 0;
  155.     UWORD comment_bytes_left, extra_len;
  156.  
  157.  
  158.  
  159. /*---------------------------------------------------------------------------
  160.     This function processes arbitrary-length (well, usually) strings.  Three
  161.     options are allowed:  SKIP, wherein the string is skipped pretty logical,
  162.     eh?); DISPLAY, wherein the string is printed to standard output after un-
  163.     dergoing any necessary or unnecessary character conversions; and FILENAME,
  164.     wherein the string is put into the filename[] array after undergoing ap-
  165.     propriate conversions (including case-conversion, if that is indicated:
  166.     see the global variable pInfo->lcflag).  The latter option should be OK,
  167.     since filename is now dimensioned at 1025, but we check anyway.
  168.  
  169.     The string, by the way, is assumed to start at the current file-pointer
  170.     position; its length is given by len.  So start off by checking length
  171.     of string:  if zero, we're already set.
  172.   ---------------------------------------------------------------------------*/
  173.  
  174.     if (!len)
  175.         return (0);             /* 0:  no error */
  176.  
  177.     switch (option) {
  178.  
  179.     /*
  180.      * First case:  print string on standard output.  First set loop vari-
  181.      * ables, then loop through the comment in chunks of OUTBUFSIZ bytes,
  182.      * converting formats and printing as we go.  The second half of the
  183.      * loop conditional was added because the file might be truncated, in
  184.      * which case comment_bytes_left will remain at some non-zero value for
  185.      * all time.  outbuf is used as a scratch buffer because it is avail-
  186.      * able (we should be either before or in between any file processing).
  187.      * [The typecast in front of the min() macro was added because of the
  188.      * new promotion rules under ANSI C; readbuf() wants an int, but min()
  189.      * returns a signed long, if I understand things correctly.  The proto-
  190.      * type should handle it, but just in case...]
  191.      */
  192.  
  193.     case DISPLAY:
  194.         comment_bytes_left = len;
  195.         block_length = OUTBUFSIZ;    /* for the while statement, first time */
  196.         while (comment_bytes_left > 0 && block_length > 0) {
  197.             if ((block_length = readbuf((char *) outbuf,
  198.                          (int) min(OUTBUFSIZ, comment_bytes_left))) <= 0)
  199.                 return (51);    /* 51:  unexpected EOF */
  200.             comment_bytes_left -= block_length;
  201.             NUKE_CRs(outbuf, block_length);     /* (modifies block_length) */
  202.  
  203.             /*  this is why we allocated an extra byte for outbuf: */
  204.             outbuf[block_length] = '\0';        /* terminate w/zero:  ASCIIZ */
  205.  
  206.             A_TO_N(outbuf);     /* translate string to native */
  207.  
  208.             printf("%s", outbuf);
  209.         }
  210.         printf("\n", outbuf);   /* assume no newline at end */
  211.         break;
  212.  
  213.     /*
  214.      * Second case:  read string into filename[] array.  The filename should
  215.      * never ever be longer than FILNAMSIZ-1 (1024), but for now we'll check,
  216.      * just to be sure.
  217.      */
  218.  
  219.     case FILENAME:
  220.         extra_len = 0;
  221.         if (len >= FILNAMSIZ) {
  222.             fprintf(stderr, "warning:  filename too long--truncating.\n");
  223.             error = 1;          /* 1:  warning error */
  224.             extra_len = len - FILNAMSIZ + 1;
  225.             len = FILNAMSIZ - 1;
  226.         }
  227.         if (readbuf(filename, len) <= 0)
  228.             return (51);        /* 51:  unexpected EOF */
  229.         filename[len] = '\0';   /* terminate w/zero:  ASCIIZ */
  230.  
  231.         A_TO_N(filename);       /* translate string to native */
  232.  
  233. #ifndef ZIPINFO
  234.         if (pInfo->lcflag)
  235.             TOLOWER(filename, filename);  /* replace with lowercase filename */
  236. #endif
  237.  
  238.         if (!extra_len)         /* we're done here */
  239.             break;
  240.  
  241.         /*
  242.          * We truncated the filename, so print what's left and then fall
  243.          * through to the SKIP routine.
  244.          */
  245.         fprintf(stderr, "[ %s ]\n", filename);
  246.         len = extra_len;
  247.         /*  FALL THROUGH...  */
  248.  
  249.     /*
  250.      * Third case:  skip string, adjusting readbuf's internal variables
  251.      * as necessary (and possibly skipping to and reading a new block of
  252.      * data).
  253.      */
  254.  
  255.     case SKIP:
  256.         LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)
  257.         break;
  258.  
  259.     /*
  260.      * Fourth case:  assume we're at the start of an "extra field"; malloc
  261.      * storage for it and read data into the allocated space.
  262.      */
  263.  
  264.     case EXTRA_FIELD:
  265.         if (extra_field != NULL)
  266.             free(extra_field);
  267.         if ((extra_field = (byte *)malloc(len)) == NULL) {
  268.             fprintf(stderr,
  269.               "warning:  extra field too long (%d).  Ignoring...\n", len);
  270.             LSEEK(cur_zipfile_bufstart + (inptr-inbuf) + len)
  271.         } else
  272.             if (readbuf((char *)extra_field, len) <= 0)
  273.                 return 51;      /* 51:  unexpected EOF */
  274.         break;
  275.  
  276.     }                           /* end switch (option) */
  277.     return error;
  278.  
  279. }                               /* end function do_string() */
  280.  
  281.  
  282.  
  283.  
  284.  
  285. #ifndef ZIPINFO
  286. #ifndef VMS
  287.  
  288. /*********************************/
  289. /*  Function dos_to_unix_time()  */
  290. /*********************************/
  291.  
  292. time_t dos_to_unix_time(ddate, dtime)
  293. unsigned ddate, dtime;
  294. {
  295.     static short yday[]={0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
  296.     int yr, mo, dy, hh, mm, ss, leap;
  297.     long m_time, days=0;
  298. #if !defined(MACOS) && !defined(MSC)
  299. #if defined(BSD) || defined(MTS)
  300.     static struct timeb tbp;
  301. #else /* !(BSD || MTS) */
  302.     extern long timezone;    /* declared in <time.h> for MSC (& Borland?) */
  303. #endif /* ?(BSD || MTS) */
  304. #endif /* !MACOS && !MSC (may need to change to DOS_OS2) */
  305.  
  306. #   define YRBASE  1970
  307.  
  308.     /* dissect date */
  309.     yr = ((ddate >> 9) & 0x7f) + (1980 - YRBASE);
  310.     mo = ((ddate >> 5) & 0x0f) - 1;
  311.     dy = (ddate & 0x1f) - 1;
  312.  
  313.     /* dissect time */
  314.     hh = (dtime >> 11) & 0x1f;
  315.     mm = (dtime >> 5) & 0x3f;
  316.     ss = (dtime & 0x1f) * 2;
  317.  
  318.     /* leap = # of leap years from BASE up to but not including current year */
  319.     leap = ((yr + YRBASE - 1) / 4);   /* leap year base factor */
  320.  
  321.     /* How many days from BASE to this year? (& add expired days this year) */
  322.     days = (yr * 365) + (leap - 492) + yday[mo];
  323.  
  324.     /* if year is a leap year and month is after February, add another day */
  325.     if ((mo > 1) && ((yr+YRBASE)%4 == 0) && ((yr+YRBASE) != 2100))
  326.         ++days;                 /* OK through 2199 */
  327.  
  328.     /* convert date & time to seconds relative to 00:00:00, 01/01/YRBASE */
  329.     m_time = ((long)(days + dy) * 86400) + ((long) hh * 3600) + (mm * 60) + ss;
  330.       /* - 1;   MS-DOS times always rounded up to nearest even second */
  331.  
  332. #if !defined(MACOS) && !defined(EMX32)
  333. #if defined(BSD) || defined(MTS)
  334.     ftime(&tbp);
  335.     m_time += tbp.timezone * 60L;
  336. #else /* !(BSD || MTS) */
  337.     tzset();                    /* set `timezone' */
  338.     m_time += timezone;         /* account for timezone differences */
  339. #endif /* ?(BSD || MTS) */
  340. #endif /* !MACOS && !EMX32 */
  341.  
  342.     if (localtime((time_t *)&m_time)->tm_isdst)
  343.         m_time -= 60L * 60L;    /* adjust for daylight savings time */
  344.  
  345.     return m_time;
  346.  
  347. } /* end function dos_to_unix_time() */
  348.  
  349. #endif /* !VMS */
  350.  
  351.  
  352.  
  353.  
  354.  
  355. /********************************/
  356. /*  Function check_for_newer()  */  /* could make this into a macro for Unix */
  357. /********************************/
  358.  
  359. int check_for_newer(filename)   /* return 1 if existing file newer or equal; */
  360. char *filename;                 /*  0 if older; -1 if doesn't exist yet */
  361. {
  362. #ifdef VMS
  363.     int dy, mo, yr, hh, mm, ss, dy2, mo2, yr2, hh2, mm2, ss2;
  364.     float sec;
  365.     char mon[4];
  366.     static char actimbuf[24], modtimbuf[24];
  367.     static char *month[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN",
  368.                             "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
  369.     struct VMStimbuf {
  370.         char *actime;           /* VMS revision date, ASCII format */
  371.         char *modtime;          /* VMS creation date, ASCII format */
  372.     } ascii_times={actimbuf,modtimbuf};
  373.  
  374.  
  375.     if (stat(filename, &statbuf))
  376.         return -1;
  377.  
  378.     if (VMSmunch(filename, GET_TIMES, &ascii_times) != RMS$_NMF)
  379.         return 0;   /* exists but can't get the time:  assume older */
  380.  
  381.     sscanf(modtimbuf, "%2d-%3s-%04d %02d:%02d:%05f", &dy, mon,
  382.       &yr, &hh, &mm, &sec);
  383.  
  384.     yr2 = ((lrec.last_mod_file_date >> 9) & 0x7f) + 1980;
  385.     if (yr > yr2)
  386.         return 1;
  387.     else if (yr < yr2)
  388.         return 0;
  389.  
  390.     for (mo = 0;  mo < 11;  ++mo)
  391.         if (!strcmp(mon, month[mo]))
  392.             break;
  393.     mo2 = ((lrec.last_mod_file_date >> 5) & 0x0f) - 1;
  394.     if (mo > mo2)
  395.         return 1;
  396.     else if (mo < mo2)
  397.         return 0;
  398.  
  399.     dy2 = (lrec.last_mod_file_date & 0x1f);
  400.     if (dy > dy2)
  401.         return 1;
  402.     else if (dy < dy2)
  403.         return 0;
  404.  
  405.     hh2 = (lrec.last_mod_file_time >> 11) & 0x1f;
  406.     if (hh > hh2)
  407.         return 1;
  408.     else if (hh < hh2)
  409.         return 0;
  410.  
  411.     mm2 = (lrec.last_mod_file_time >> 5) & 0x3f;
  412.     if (mm > mm2)
  413.         return 1;
  414.     else if (mm < mm2)
  415.         return 0;
  416.  
  417.     /* round to nearest 2 secs--may become 60, but doesn't matter for compare */
  418.     ss = (int)(sec + 1.) & -2;
  419.     ss2 = (lrec.last_mod_file_time & 0x1f) * 2;
  420.     if (ss >= ss2)
  421.         return 1;
  422.  
  423.     return 0;
  424.  
  425. #else /* !VMS */        /* round up filetime to nearest 2 secs --v  */
  426.     return stat(filename, &statbuf)?  -1 :
  427.       ( ((statbuf.st_mtime & 1)? statbuf.st_mtime+1 : statbuf.st_mtime) >=
  428.       dos_to_unix_time(lrec.last_mod_file_date, lrec.last_mod_file_time) );
  429. #endif /* ?VMS */
  430.  
  431. } /* end function check_for_newer() */
  432.  
  433.  
  434.  
  435.  
  436.  
  437. /***************************/
  438. /*  Function dateformat()  */
  439. /***************************/
  440.  
  441. int dateformat()
  442. {
  443.  
  444. /*-----------------------------------------------------------------------------
  445.   For those operating systems which support it, this function returns a value
  446.   which tells how national convention says that numeric dates are displayed.
  447.  
  448.   Return values are DF_YMD, DF_DMY and DF_MDY.  The meanings should be fairly
  449.   obvious.
  450.  -----------------------------------------------------------------------------*/
  451.  
  452. #ifdef OS2
  453.     COUNTRYINFO    ctryi;
  454.     COUNTRYCODE    ctryc;
  455. #ifdef __32BIT__
  456.     ULONG          cbCountryInfo;
  457. #else
  458.     USHORT         cbCountryInfo;
  459. #endif
  460.  
  461.  
  462.     ctryc.country = ctryc.codepage = 0;
  463.     if (DosGetCtryInfo(sizeof ctryi, &ctryc, &ctryi, &cbCountryInfo) != NO_ERROR)
  464.         return DF_MDY;
  465.     else
  466.         switch (ctryi.fsDateFmt) {
  467.             case 0 /* DATEFMT_MM_DD_YY */ :
  468.                 return DF_MDY;
  469.             case 1 /* DATEFMT_DD_MM_YY */ :
  470.                 return DF_DMY;
  471.             case 2 /* DATEFMT_YY_MM_DD */ :
  472.                 return DF_YMD;
  473.         }
  474. #else /* !OS2 */
  475. #ifdef MSDOS
  476.     unsigned short int CountryInfo[18];
  477.     union REGS regs;
  478.     struct SREGS sregs;
  479.  
  480.  
  481.     regs.x.ax = 0x3800;
  482.     regs.x.dx = FP_OFF(CountryInfo);
  483.     sregs.ds  = FP_SEG(CountryInfo);
  484.     int86x(0x21, ®s, ®s, &sregs);
  485.     switch(CountryInfo[0]) {
  486.         case 0:
  487.             return DF_MDY;
  488.         case 1:
  489.             return DF_DMY;
  490.         case 2:
  491.             return DF_YMD;
  492.     }
  493. #endif /* !MSDOS */
  494. #endif /* ?OS2 */
  495.  
  496.     return DF_MDY;   /* default for Unix, VMS, etc. */
  497. }                               /* end function dateformat() */
  498.  
  499. #endif /* !ZIPINFO */
  500.  
  501.  
  502.  
  503.  
  504.  
  505. #ifdef EBCDIC
  506.  
  507. /*
  508.  * This is the MTS ASCII->EBCDIC translation table. It provides a 1-1
  509.  * translation from ISO 8859/1 8-bit ASCII to IBM Code Page 37 EBCDIC.
  510.  */
  511.  
  512. unsigned char ebcdic[] =
  513. {
  514.     0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, 0x16, 0x05, 0x25, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
  515.     0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f,
  516.     0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61,
  517.     0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f,
  518.     0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6,
  519.     0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xba, 0xe0, 0xbb, 0xb0, 0x6d,
  520.     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
  521.     0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07,
  522.     0x20, 0x21, 0x22, 0x23, 0x24, 0x15, 0x06, 0x17, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x1b,
  523.     0x30, 0x31, 0x1a, 0x33, 0x34, 0x35, 0x36, 0x08, 0x38, 0x39, 0x3a, 0x3b, 0x04, 0x14, 0x3e, 0xff,
  524.     0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, 0xbd, 0xb4, 0x9a, 0x8a, 0x5f, 0xca, 0xaf, 0xbc,
  525.     0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab,
  526.     0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77,
  527.     0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xad, 0xae, 0x59,
  528.     0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57,
  529.     0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf
  530. };
  531.  
  532. #endif                          /* EBCDIC */
  533.  
  534.  
  535.  
  536.  
  537.  
  538. /*************************/
  539. /*  Function makeword()  */
  540. /*************************/
  541.  
  542. UWORD makeword(b)
  543. byte *b;
  544.  /*
  545.   * Convert Intel style 'short' integer to non-Intel non-16-bit
  546.   * host format.  This routine also takes care of byte-ordering.
  547.   */
  548. {
  549. /*
  550.     return  ( ((UWORD)(b[1]) << 8)  |  (UWORD)(b[0]) );
  551.  */
  552.     return ((b[1] << 8) | b[0]);
  553. }
  554.  
  555.  
  556.  
  557.  
  558.  
  559. /*************************/
  560. /*  Function makelong()  */
  561. /*************************/
  562.  
  563. ULONG makelong(sig)
  564. byte *sig;
  565.  /*
  566.   * Convert intel style 'long' variable to non-Intel non-16-bit
  567.   * host format.  This routine also takes care of byte-ordering.
  568.   */
  569. {
  570.     return (((ULONG) sig[3]) << 24)
  571.         + (((ULONG) sig[2]) << 16)
  572.         + (((ULONG) sig[1]) << 8)
  573.         + ((ULONG) sig[0]);
  574. }
  575.  
  576.  
  577.  
  578.  
  579.  
  580. #ifdef VMS
  581.  
  582. /***************************/
  583. /*  Function return_VMS()  */
  584. /***************************/
  585.  
  586. void return_VMS(zip_error)
  587. int zip_error;
  588. {
  589. #ifdef RETURN_CODES
  590. /*---------------------------------------------------------------------------
  591.     Do our own, explicit processing of error codes and print message, since
  592.     VMS misinterprets return codes as rather obnoxious system errors ("access
  593.     violation," for example).
  594.   ---------------------------------------------------------------------------*/
  595.  
  596.     switch (zip_error) {
  597.  
  598.     case 0:
  599.         break;                  /* life is fine... */
  600.     case 1:
  601.         fprintf(stderr, "\n[return-code 1:  warning error \
  602. (e.g., failed CRC or unknown compression method)]\n");
  603.         break;
  604.     case 2:
  605.     case 3:
  606.         fprintf(stderr, "\n[return-code %d:  error in zipfile \
  607. (e.g., can't find local file header sig)]\n",
  608.                 zip_error);
  609.         break;
  610.     case 4:
  611.     case 5:
  612.     case 6:
  613.     case 7:
  614.     case 8:
  615.         fprintf(stderr, "\n[return-code %d:  insufficient memory]\n",
  616.                 zip_error);
  617.         break;
  618.     case 9:
  619.         fprintf(stderr, "\n[return-code 9:  zipfile not found]\n");
  620.         break;
  621.     case 10:                    /* this is the one that gives "access violation," I think */
  622.         fprintf(stderr, "\n[return-code 10:  bad or illegal parameters \
  623. specified on command line]\n");
  624.         break;
  625.     case 11:                    /* I'm not sure this one is implemented, but maybe soon? */
  626.         fprintf(stderr, "\n[return-code 11:  no files found to \
  627. extract/view/etc.]\n");
  628.         break;
  629.     case 50:
  630.         fprintf(stderr, "\n[return-code 50:  disk full \
  631. (or otherwise unable to open output file)]\n");
  632.         break;
  633.     case 51:
  634.         fprintf(stderr, "\n[return-code 51:  unexpected EOF in zipfile \
  635. (i.e., truncated)]\n");
  636.         break;
  637.     default:
  638.         fprintf(stderr, "\n[return-code %d:  unknown return-code \
  639. (who put this one in?  Wasn't me...)]\n",
  640.                 zip_error);
  641.         break;
  642.     }
  643. #endif                          /* RETURN_CODES */
  644.  
  645.     exit(0);                    /* everything okey-dokey as far as VMS concerned */
  646. }
  647.  
  648. #endif                          /* VMS */
  649.  
  650.  
  651.  
  652.  
  653.  
  654. #ifdef ZMEM                     /* memset, memcpy for systems without them */
  655.  
  656. /***********************/
  657. /*  Function memset()  */
  658. /***********************/
  659.  
  660. char *memset(buf, init, len)
  661. register char *buf, init;       /* buffer loc and initializer */
  662. register unsigned int len;      /* length of the buffer */
  663. {
  664.     char *start;
  665.  
  666.     start = buf;
  667.     while (len--)
  668.         *(buf++) = init;
  669.     return (start);
  670. }
  671.  
  672.  
  673.  
  674.  
  675.  
  676. /***********************/
  677. /*  Function memcpy()  */
  678. /***********************/
  679.  
  680. char *memcpy(dst, src, len)
  681. register char *dst, *src;
  682. register unsigned int len;
  683. {
  684.     char *start;
  685.  
  686.     start = dst;
  687.     while (len-- > 0)
  688.         *dst++ = *src++;
  689.     return (start);
  690. }
  691.  
  692. #endif                          /* ZMEM */
  693.